home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / WINSYS.PAK / MSGTHRED.H < prev    next >
C/C++ Source or Header  |  1997-05-06  |  6KB  |  224 lines

  1. //----------------------------------------------------------------------------
  2. // Borland WinSys Library
  3. // Copyright (c) 1995, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   5.12  $
  6. //
  7. // Definition of message queue oriented thread class support. Degenerates to a
  8. // simple message queue owner under non-threaded environments
  9. //----------------------------------------------------------------------------
  10. #if !defined(WINSYS_MSGTHRED_H)
  11. #define WINSYS_MSGTHRED_H
  12.  
  13. #if !defined(WINSYS_DEFS_H)
  14. # include <winsys/defs.h>
  15. #endif
  16. #if defined(BI_MULTI_THREAD) && !defined(CLASSLIB_THREAD_H)
  17. # include <classlib/thread.h>
  18. #endif
  19. #if !defined(WINSYS_WSYSINC_H)
  20. #  include <winsys/wsysinc.h>
  21. #endif
  22.  
  23. #if defined(BI_NAMESPACE)
  24. namespace ClassLib {
  25. #endif
  26.  
  27. //
  28. // class TMsgThread
  29. // ~~~~~ ~~~~~~~~~~
  30. #if defined(BI_MULTI_THREAD_RTL)
  31. class _WSYSCLASS TMsgThread :  public TThread
  32. {
  33. #else
  34. class _WSYSCLASS TMsgThread
  35. {
  36.   public:
  37.     enum TCurrent {Current};
  38. #endif
  39.  
  40.   public:
  41.     TMsgThread(TCurrent);
  42.  
  43.     // Message queue functions
  44.     //
  45.     virtual int      MessageLoop();
  46.     virtual bool     IdleAction(long idleCount);
  47.     virtual bool     ProcessMsg(MSG& msg);
  48.  
  49.     bool             PumpWaitingMessages();
  50.     void             FlushQueue();
  51.  
  52.     // Is this queue thread running its message loop?
  53.     //
  54.     bool             IsRunning() const;
  55.  
  56.     // Message queue thread synchronization mechanism. Real multi-threading
  57.     // requires compiler & RTL support (-MT)
  58.     //
  59. #if defined(BI_MULTI_THREAD_RTL)
  60.     void    EnableMultiThreading(bool enable);
  61.     TMutex* GetMutex();
  62.  
  63.     class _WSYSCLASS TQueueLock {
  64.       public:
  65.         TQueueLock(TMsgThread& app);
  66.        ~TQueueLock();
  67.         void Release(bool relinquish = false);
  68.       private:
  69.         _TCHAR Lock[sizeof(TMutex::TLock)];
  70.         bool Locked;
  71.     };
  72. #endif
  73.  
  74.   protected:
  75. #if defined(BI_MULTI_THREAD_RTL)  // No real threads without RTL support
  76.     TMsgThread();
  77. #endif
  78.  
  79.     // Override this for created threads, app thread is Run() from OwlMain
  80.     //
  81.     virtual int      Run();
  82.  
  83.     virtual void     InitInstance();
  84.     virtual int      TermInstance(int status);
  85.  
  86.     bool          BreakMessageLoop;     // Message loop is broken via WM_QUIT
  87.     int           MessageLoopResult;    // Return value from message loop
  88.  
  89.     bool          LoopRunning;          // Track if the loop is running
  90.  
  91. #if defined(BI_MULTI_THREAD_RTL)
  92.     class _WSYSCLASS TAppMutex {
  93.       public:
  94.         TAppMutex();
  95.        ~TAppMutex();
  96.         TMutex* GetMutex();
  97.       private:
  98.         char* Mutex[sizeof(TMutex)];
  99.     };
  100.  
  101.     TAppMutex     Mutex;                // Mutex to prevent multiple threads
  102.                                         // from processing messages at the
  103.                                         // same time.
  104.   private:
  105.     bool          UseMutex;
  106. #endif
  107. };
  108.  
  109. #if defined(BI_NAMESPACE)
  110. }     // namespace ClassLib 
  111. #endif
  112.  
  113. //----------------------------------------------------------------------------
  114. // Inline implementations
  115.  
  116. //
  117. // Return true if the thread is currently running.
  118. //
  119. inline bool TMsgThread::IsRunning() const
  120. {
  121.   return LoopRunning;
  122. }
  123.  
  124. #if defined(BI_MULTI_THREAD_RTL)
  125.  
  126. # if !defined(WINSYS_SYSTEM_H)
  127. #   include <winsys/system.h>  
  128. # endif
  129.  
  130. //
  131. // Enable/disable the use of the mutex to synchronize access to the msg queue.
  132. // Only when enabled, will the TMsgThread lock its msg queue mutex.
  133. //
  134. inline void TMsgThread::EnableMultiThreading(bool enable)
  135. {
  136.   UseMutex = enable ? TSystem::SupportsThreads() : false;
  137. }
  138.  
  139. //
  140. // Get this msg thread's mutex. Return 0 if mutexes are not supported, or are
  141. // not enabled for this thread.
  142. //
  143. inline TMutex* TMsgThread::GetMutex()
  144. {
  145.   return UseMutex ? Mutex.GetMutex() : 0;
  146. }
  147.  
  148. //
  149. // The mutex is always constructed/destructed if the system supports threads
  150. //
  151. inline TMsgThread::TAppMutex::TAppMutex()
  152. {
  153.   if (TSystem::SupportsThreads()) {
  154. #if defined(BI_NAMESPACE)
  155.     ClassLib::new(Mutex) TMutex;
  156. #else
  157.     new(Mutex) TMutex;
  158. #endif
  159.   }
  160. }
  161.  
  162. //
  163. inline TMsgThread::TAppMutex::~TAppMutex()
  164. {
  165.   if (TSystem::SupportsThreads())
  166. #if defined(BI_COMP_MSC)  
  167.     REINTERPRET_CAST(TMutex*,Mutex)->~TMutex();
  168. //    ((TMutex*)Mutex)->TMutex::~TMutex();
  169. #else
  170.     REINTERPRET_CAST(TMutex*,Mutex)->TMutex::~TMutex();
  171. #endif
  172. }
  173.  
  174. //
  175. // Get the apps mutex. Return 0 if mutexs are not supported, or are not enabled
  176. // for this app.
  177. //
  178. inline TMutex* TMsgThread::TAppMutex::GetMutex()
  179. {
  180.   return REINTERPRET_CAST(TMutex*,Mutex);
  181. }
  182.  
  183. //
  184. // Only lock if the mutex is available. Do nothing otherwise. Use placement
  185. // new to construct the real lock in place.
  186. //
  187. inline TMsgThread::TQueueLock::TQueueLock(TMsgThread& app)
  188. {
  189.   TMutex* appMutex = app.GetMutex();
  190.   Locked = appMutex ? true : false;
  191.   if (Locked)
  192. #if defined(BI_NAMESPACE)
  193.     ClassLib::new(Lock) TMutex::TLock(*appMutex);
  194. #else
  195.     new(Lock) TMutex::TLock(*appMutex);
  196. #endif
  197. }
  198.  
  199. //
  200. // Destruct the real lock if it was constructed (locked)
  201. //
  202. inline TMsgThread::TQueueLock::~TQueueLock()
  203. {
  204.   if (Locked)
  205. #if defined(BI_COMP_MSC)
  206.     REINTERPRET_CAST(TMutex::TLock*,Lock)->~TLock();
  207. #else
  208.     REINTERPRET_CAST(TMutex::TLock*,Lock)->TMutex::Lock::~Lock();
  209. #endif
  210. }
  211.  
  212. //
  213. // Release the real lock if it was locked
  214. //
  215. inline void TMsgThread::TQueueLock::Release(bool relinquish)
  216. {
  217.   if (Locked)
  218.     REINTERPRET_CAST(TMutex::TLock*,Lock)->Release(relinquish);
  219. }
  220.  
  221. #endif  // BI_MULTI_THREAD_RTL
  222.  
  223. #endif  // WINSYS_MSGTHRED_H
  224.